﻿using System.ComponentModel;
using K9Nano.Extensions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection;

namespace K9Nano.Authorization;

public static class ActionPermissionProvider
{
    public static void CreatePermissions(IServiceProvider serviceProvider)
    {
        var permissionCatalog = serviceProvider.GetRequiredService<IPermissionCatalog>();
        var actionDescriptorCollectionProvider = serviceProvider.GetRequiredService<IActionDescriptorCollectionProvider>();

        foreach (var actionDescriptor in actionDescriptorCollectionProvider.ActionDescriptors.Items)
        {
            if (actionDescriptor is ControllerActionDescriptor controllerAction)
            {
                if (controllerAction.EndpointMetadata.All(a => a is not Microsoft.AspNetCore.Mvc.ApiControllerAttribute))
                {
                    continue;
                }

                if (controllerAction.EndpointMetadata.Any(a => a is PermissionIgnoreAttribute))
                {
                    continue;
                }

                if (controllerAction.EndpointMetadata.Any(a => a is AllowAnonymousAttribute))
                {
                    continue;
                }

                var permission = new Permission
                {
                    Group = "API",
                    Name = controllerAction.ToActionPrimaryId(),
                };

                if (controllerAction.ControllerTypeInfo.TryGetCustomAttribute<DescriptionAttribute>(false, out var controllerDescAttr))
                {
                    permission.Description = $"【{controllerDescAttr!.Description}】";
                }

                if (controllerAction.MethodInfo.TryGetCustomAttribute<DescriptionAttribute>(false, out var actionDescAttr))
                {
                    permission.Description += actionDescAttr!.Description;
                }

                permissionCatalog.Add(permission);
            }
        }
    }
}